Virtualisation KVM

François Goffinet linux.goffinet.org  64-82 minutes

 

Introduction

Références à lire

Scripts de préparation et d’automation

On trouvera sur le dépot GIT https://github.com/goffinet/virt-scripts des scripts utiles à ce chapitre.

apt-get update && apt-get upgrade -y && apt-get install git -y

cd ~

git clone https://github.com/goffinet/virt-scripts

cd virt-scripts

Objectifs

  1. 1.Concepts virtualisation KVM 

1. Concepts

1.1. Terminologie

1.2. Typologie des architectures de virtualisation

KVM est un hyperviseur de type 1 qui s’utilise aussi bien dans :

1.3. Machine virtuelle

Sur le plan technique, en général et particulièrement avec KVM, une machine virtuelle (VM) est représentée par :

  1. 1.un fichier de définition qui reprend les caractéristiques de la machine, par défaut situé (en format XML) dans /etc/libvirt/qemu/. 

  2. 2.un ou des fichier(s) qui représentent les disques par défaut placés dans /var/lib/libvirt/images/. 

Les principales ressources de virtualisation sont :

Mais pour fonctionner, une VM a aussi besoin de bien d’autres interfaces matérielles qui peuvent être émulées ou para-virtualisées.

1.4. KVM

KVM Kernel-based Virtual Machine :

Vue du noyau :

Features :

 

1.5. Qemu

Qemu est un émulateur de diverses architectures dont x86 (Hyperviseur de type 2). Combiné au pilote KVM, il permet de réaliser de l’accélération Hardware (HVM).

L’outil de base qemu-img permet de créer et de gérer des images disque.

En format local les images disques peuvent se trouver en formats :

Par ailleurs, on peut utiliser directement des volumes logiques LVM.

1.6. Libvirt

libvirt un API de virtualisation Open Source qui s’interface avec un hyperviseur pour administrer les VMs.

1.7. Outils de base

1.8. Outils libguestfs

libguestfs est un ensemble d’outils qui permettent d’accéder aux disques des machines virtuelles et de les modifier.

Ces outils permettent de :

1.9. Pilotes et périphériques PV virtio

Périphérique réseau virtio.

 

1.10. Interfaces graphiques

2. Installer KVM et ses outils de gestion

Les instructions VT doivent être activées dans le Bios (Netsted Virtualization) :

grep -E 'svm|vmx' /proc/cpuinfo

ou encore

lscpu | grep Virtualisation

Mise à jour du sytème et installation des paquets KVM :

En RHEL7/Centos7.

yum update -y

yum group install "Virtualization Host" "Virtualization Client"

 

yum -y install \

qemu-kvm \

dejavu-lgc-sans-fonts \

libguestfs-tools

Démarrer le service libvirtd :

systemctl enable libvirtd && systemctl start libvirtd

Démarrer le service chronyd :

# systemctl enable chronyd && systemctl start chronyd

En Debian 8.

apt-get update && sudo apt-get -y upgrade

apt-get -y install qemu-kvm libvirt-bin virtinst virt-viewer libguestfs-tools virt-manager uuid-runtime

Démarrage du commutateur virtuel par défaut.

virsh net-start default

virsh net-autostart default

Vérification du chargement du module kvm.

Libvirt propose un outil de vérification de l’hôte.

virt-host-validate

  QEMU: Vérification for hardware virtualization                                 : PASS

  QEMU: Vérification for device /dev/kvm                                         : PASS

  QEMU: Vérification for device /dev/vhost-net                                   : PASS

  QEMU: Vérification for device /dev/net/tun                                     : PASS

  LXC: Vérification pour Linux >= 2.6.26                                        : PASS

Vérification du démarrage de libvirt :

systemctl status libvirtd

 

Configuration du réseau par défaut :

Une interface bridge virbr0 192.168.122.1 est “natée” à l’interface physique. Le démon dnsmasq fournit le service DNS/DHCP.

 

ip add sh virbr0

ip route

iptables -t nat -L -n -v

cat /proc/sys/net/ipv4/ip_forward

L’emplacement par défaut de l’espace de stockage des disques est /var/lib/libvirt/images/. La définition des machines virtuelles est située dans /etc/libvirt/qemu/.

Il est peut-être plus aisé de désactiver pour l’instant firewalld (systemctl stop firewalld).

On propose ici un script de préparation de l’hôte de virtualisation :

https://raw.githubusercontent.com/goffinet/virt-scripts/master/autoprep.sh

3. Création de VMs et administration de base

3.1. Créer une machine virtuelle avec virt-manager

Virt-manager est un outil graphique de gestion des hyperviseurs connecté via libvirt.

Dans une session X Window, suivre Quick Start with virt-manager ou encore KVM, Qemu, libvirt en images.

3.2. Administration de base avec virsh

A ajouter : images à exécuter

Avec libvirt et KVM, une “Machine Virtuelle (VM)” est appelée un “Domaine”.

Démarrage d’un domaine :

Arrêt d’un domaine :

Extinction d’un domaine (comme on retire une prise de courant, il ne s’agit pas d’effacer le domaine) :

Pour retirer une VM (le ou les disques associés persistent) :

Pour retirer un domaine (et en effaçant ses disques) :

virsh undefine vm1 --remove-all-storage

Redémarrage d’un domaine :

Informations détaillées :

Liste des domaines :

Démarrage du domaine au démarrage de l’hôte :

Désactiver l’activation au démarrage :

virsh autostart vm1 --disable

Accéder à la console série (texte) du domaine :

Accéder à la console graphique du domaine :

4. Scripts d’installation

La commande qui permet de créer une machine virtuelle et de la lancer (pour y installer un système d’exploitation) est virt-install. Cette commande peut comporter un certain nombre de paramètres. Il est plus intéressant de travailler avec des scripts.

Dans le but de cloner un domaine existant, on s’intéressa à ce qui constitue fondamentalement une machine virtuelle :

Les procédures de création ou de mise à jour d’objet (réseau, volume, domaine) avec la commande virsh consiste à manipuler des définitions XML :

4.1. Un premier script virt-install

On peut créer une machine virtuelle lancer une installation à partir du shell avec virt-install et des options.

Création et lancement d’une VM :

#!/bin/bash

# vm-install1.sh

 

# local path to the iso

iso=/var/lib/iso/CentOS-7-x86_64-DVD-1611.iso

 

# Stop and undefine the VM

/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

 

# graphical console

# via local ISO

virt-install \

--virt-type kvm \

--name=$1 \

--disk path=/var/lib/libvirt/images/$1.img,size=8 \

--ram=1024 \

--vcpus=1 \

--os-variant=rhel7 \

--graphics vnc \

--console pty,target_type=serial \

--cdrom $iso

4.2. Export manuel d’une VM

Avant de procéder à un export, il est préférable de suspendre la VM d’origine :

On peut rediriger un “dump” de la VM d’origine dans un fichier xml.

virsh dumpxml vm1 > vm2.xml

Ensuite, il faut adapter ce fichier en retirant la valeur id et le champ uuid en modifiant le champ name, la balise source file qui désigne l’emplacement du nouveau disque, le champ mac address et en supprimant des balises entre </devices> et </domain>.

Le second élément nécessaire à l’exécution de la VM est un disque dédié, soit la copie du disque de la machine originale :

cp /var/lib/libvirt/images/vm1.img /var/lib/libvirt/images/vm2.img

Enfin, on peut intégrer la machine à libvirtet la démarrer :

virsh define vm2.xml

 

virsh start vm2

 

A lire attentivement, voici le fichier vm2.xml adapté (uuid, devices, disks, mac):

<domain type='kvm'>

  <name>vm2</name>

  <memory unit='KiB'>1048576</memory>

  <currentMemory unit='KiB'>1048576</currentMemory>

  <vcpu placement='static'>1</vcpu>

  <resource>

    <partition>/machine</partition>

  </resource>

  <os>

    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>

    <boot dev='hd'/>

  </os>

  <features>

    <acpi/>

    <apic/>

    <pae/>

  </features>

  <cpu mode='custom' match='exact'>

    <model fallback='allow'>Westmere</model>

  </cpu>

  <clock offset='utc'>

    <timer name='rtc' tickpolicy='catchup'/>

    <timer name='pit' tickpolicy='delay'/>

    <timer name='hpet' present='no'/>

  </clock>

  <on_poweroff>destroy</on_poweroff>

  <on_reboot>restart</on_reboot>

  <on_crash>restart</on_crash>

  <devices>

    <emulator>/usr/libexec/qemu-kvm</emulator>

    <disk type='file' device='disk'>

      <driver name='qemu' type='raw'/>

      <source file='/var/lib/libvirt/images/vm2.img'/>

      <backingStore/>

      <target dev='vda' bus='virtio'/>

      <alias name='virtio-disk0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>

    </disk>

    <controller type='usb' index='0' model='ich9-ehci1'>

      <alias name='usb0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>

    </controller>

    <controller type='usb' index='0' model='ich9-uhci1'>

      <alias name='usb0'/>

      <master startport='0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>

    </controller>

    <controller type='usb' index='0' model='ich9-uhci2'>

      <alias name='usb0'/>

      <master startport='2'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>

    </controller>

    <controller type='usb' index='0' model='ich9-uhci3'>

      <alias name='usb0'/>

      <master startport='4'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>

    </controller>

    <controller type='pci' index='0' model='pci-root'>

      <alias name='pci.0'/>

    </controller>

    <interface type='bridge'>

      <mac address='52:54:00:8a:c3:2a'/>

      <source bridge='virbr0'/>

      <target dev='vnet0'/>

      <model type='virtio'/>

      <alias name='net0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>

    </interface>

    <serial type='pty'>

      <source path='/dev/pts/0'/>

      <target type='isa-serial' port='0'/>

      <alias name='serial0'/>

    </serial>

    <console type='pty' tty='/dev/pts/0'>

      <source path='/dev/pts/0'/>

      <target type='serial' port='0'/>

      <alias name='serial0'/>

    </console>

    <input type='tablet' bus='usb'>

      <alias name='input0'/>

    </input>

    <memballoon model='virtio'>

      <alias name='balloon0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>

    </memballoon>

  </devices>

</domain>

 

4.3. Clonage avec virt-clone

L’utilitaire virt-clone permet de cloner (à l’identique) une VM. virt-cloneprend la peine de générer une nouvelle adresse MAC et un nouvel uuid pour le domaine. Il s’occupe également de dupliquer le ou les disques attachés au domaine.

Imaginons que l’on veuille cloner proprement la machine vm1 en machine vm2 dans le but de :

Attention, il faudra malgré tout modifier le fichier de configuration du réseau en retirant l’adresse mac et l’uuid dans le système d’exploitation invité. (/etc/sysconfig/network-scripts/ifcfg-*) si on désire exécuter le domaine original et son clone sur le même réseau ou si l’adresse IP est fixe.

Avant tout, vérifions l’état de la machine. Mettons-la en suspension pour assurer une copie correcte des disques :

virsh list

 ID    Nom                            État

----------------------------------------------------

 73    vm1                            en cours d'exécution

virsh suspend vm1

Domaine vm1 suspendu

virsh list

 ID    Nom                            État

----------------------------------------------------

 73    vm1                            mis en pause

Procédons au clonage :

virt-clone \

--original vm1 \

--name vm2 \

--file /var/lib/libvirt/images/vm2.img

virsh list --all

 ID    Nom                            État

----------------------------------------------------

 73    vm1                            mis en pause

 -     vm2                            fermé

Reprise de la machine :

virsh resume vm1

Domaine vm1 réactivé

4.4 Sysprep Linux

Pour la transformation d’une machine virtuelle en modèle (template), on peut utiliser virt-sysprep qui vient avec libguestfs, avant le clonage pour remettre à zéro ses propriétés.

# virt-sysprep --list-operations

abrt-data * Remove the crash data generated by ABRT

bash-history * Remove the bash history in the guest

blkid-tab * Remove blkid tab in the guest

ca-certificates   Remove CA certificates in the guest

crash-data * Remove the crash data generated by kexec-tools

cron-spool * Remove user at-jobs and cron-jobs

customize * Customize the guest

dhcp-client-state * Remove DHCP client leases

dhcp-server-state * Remove DHCP server leases

dovecot-data * Remove Dovecot (mail server) data

firewall-rules   Remove the firewall rules

flag-reconfiguration   Flag the system for reconfiguration

fs-uuids   Change filesystem UUIDs

kerberos-data   Remove Kerberos data in the guest

logfiles * Remove many log files from the guest

lvm-uuids * Change LVM2 PV and VG UUIDs

machine-id * Remove the local machine ID

mail-spool * Remove email from the local mail spool directory

net-hostname * Remove HOSTNAME in network interface configuration

net-hwaddr * Remove HWADDR (hard-coded MAC address) configuration

pacct-log * Remove the process accounting log files

package-manager-cache * Remove package manager cache

pam-data * Remove the PAM data in the guest

puppet-data-log * Remove the data and log files of puppet

rh-subscription-manager * Remove the RH subscription manager files

rhn-systemid * Remove the RHN system ID

rpm-db * Remove host-specific RPM database files

samba-db-log * Remove the database and log files of Samba

script * Run arbitrary scripts against the guest

smolt-uuid * Remove the Smolt hardware UUID

ssh-hostkeys * Remove the SSH host keys in the guest

ssh-userdir * Remove ".ssh" directories in the guest

sssd-db-log * Remove the database and log files of sssd

tmp-files * Remove temporary files

udev-persistent-net * Remove udev persistent net rules

user-account   Remove the user accounts in the guest

utmp * Remove the utmp file

yum-uuid * Remove the yum UUID

5. Miroir d’installation HTTP

5.1. Miroir local

Les sources d’installation doivent contenir au minimum ceci :

{product path}

   |

   +--base

   |

   +--RPMS

product path :

base : metadonnées

RPMS : Fichiers Red Hat Package Manager

Repo HTTP

Installer Apache :

yum -y install httpd

systemctl enable httpd.service && systemctl start httpd.service

 

Télécharger une image

mkdir -p /var/lib/iso

cd /var/lib/iso

wget https://centos.mirrors.ovh.net/ftp.centos.org/7/isos/x86_64/CentOS-7-x86_64-DVD-1611.iso

Monter l’ISO :

mount -o loop,ro CentOS*.iso /mnt

Copier les fichiers

mkdir /var/www/html/repo/

 

cp -rp /mnt/* /var/www/html/repo/

 

chcon -R -t httpd_sys_content_t /var/www/html

Monter l’ISO directement dans /var/www/html/repo/ est une alternative.

Miroirs publics externes

5.2. Support d’installation HTTP

Création et lancement d’une VM :

#!/bin/bash

# vm-install2.sh

 

# KVM Host IP

bridge=192.168.122.1

 

# Repo URL

mirror=https://$bridge/repo

#mirror=https://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64

#mirror=https://ftp.belnet.be/ftp.centos.org/7/os/x86_64

#mirror=https://mirror.i3d.net/pub/centos/7/os/x86_64

 

# Stop and undefine the VM

/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

 

# graphical console, bridged

# via http repo

virt-install \

--virt-type kvm \

--name=$1 \

--disk path=/var/lib/libvirt/images/$1.img,size=8 \

--ram=1024 \

--vcpus=1 \

--os-variant=rhel7 \

--network bridge=virbr0 \

--graphics vnc \

--console pty,target_type=serial \

--location $mirror

6. Installation automatique

6.1. Installation Kickstart

Kickstart permet d’automatiser les installations RHEL/Fedora/Centos (et d’autres) en indiquant un fichier de configuration qui est lu avant le logiciel d’installation Anaconda.

Documentation Kickstart

mkdir /var/www/html/conf/

 

touch vm.ks /var/www/html/conf/

 

chcon -R -t httpd_sys_content_t /var/www/html

Ce fichier de configuration est rédigé :

less /root/anaconda-ks.cfg

yum install system-config-kickstart

 

system-config-kickstart

6.2. Installation automatique en console graphique

Voici la configuration d’une installation simple avec un fichier /var/www/html/conf/vm.ks :

# File /var/www/html/conf/vm.ks

 

keyboard --vckeymap=be-oss --xlayouts='be (oss)'

lang fr_BE.UTF-8

network --onboot=on --bootproto=dhcp --device=link --hostname=localhost.localdomain

rootpw testtest

services --enabled="chronyd"

timezone Europe/Paris --isUtc

bootloader --location=mbr --boot-drive=vda

clearpart --all --initlabel --drives=vda

ignoredisk --only-use=vda

part pv.0 --fstype="lvmpv" --ondisk=vda --size=5000

part /boot --fstype="xfs" --ondisk=vda --size=500

volgroup vg0 --pesize=4096 pv.0

logvol swap  --fstype="swap" --size=500 --name=swap --vgname=vg0

logvol /  --fstype="xfs" --size=3072 --name=root --vgname=vg0

 

%packages --ignoremissing

@core

chrony

%end

reboot

Avec la machine virtuelle :

#!/bin/bash

# vm-install3.sh

 

bridge=192.168.122.1

mirror=https://$bridge/repo

#mirror=https://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64

#mirror=https://ftp.belnet.be/ftp.centos.org/7/os/x86_64

#mirror=https://mirror.i3d.net/pub/centos/7/os/x86_64

 

#Stop and undefine the VM

/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

 

# Graphical console, bridged, HD qcow2

# HTTP + Kickstart

virt-install \

--virt-type kvm \

--name=$1 \

--disk path=/var/lib/libvirt/images/$1.qcow2,size=16,format=qcow2 \

--ram=1024 \

--vcpus=1 \

--os-variant=rhel7 \

--network bridge=virbr0 \

--graphics vnc \

--console pty,target_type=serial \

--location $mirror \

-x ks=https://$bridge/conf/vm.ks

6.3. Installation automatique en console texte

Voici la configuration d’une installation simple en console texte avec un fichier /var/www/html/conf/vm2.ksrevu par system-config-kickstart :

# File /var/www/html/conf/vm2.ks

#platform=x86, AMD64, ou Intel EM64T

#version=DEVEL

# Install OS instead of upgrade

install

# Keyboard layouts

# old format: keyboard be-latin1

# new format:

keyboard --vckeymap=be-oss --xlayouts='be (oss)'

# Reboot after installation

reboot

# Root password

rootpw --plaintext testtest

# System timezone

timezone Europe/Paris

# System language

lang fr_BE

# Firewall configuration

firewall --disabled

# Network information

network  --bootproto=dhcp --device=link

# System authorization information

auth  --useshadow  --passalgo=sha512

# Use text mode install

text

# SELinux configuration

selinux --disabled

# Do not configure the X Window System

skipx

 

# System services

services --enabled="chronyd"

 

bootloader --location=mbr --boot-drive=vda

clearpart --all --initlabel --drives=vda

ignoredisk --only-use=vda

part pv.0 --fstype="lvmpv" --ondisk=vda --size=5000

part /boot --fstype="xfs" --ondisk=vda --size=500

volgroup vg0 --pesize=4096 pv.0

logvol swap  --fstype="swap" --size=500 --name=swap --vgname=vg0

logvol /  --fstype="xfs" --size=3072 --name=root --vgname=vg0

 

%packages --ignoremissing

@core

chrony

 

%end

 

Avec la machine virtuelle :

#!/bin/bash

# vm-install4.sh

 

bridge=192.168.122.1

mirror=https://$bridge/repo

#mirror=https://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64

#mirror=https://ftp.belnet.be/ftp.centos.org/7/os/x86_64

#mirror=https://mirror.i3d.net/pub/centos/7/os/x86_64

 

#Stop and undefine the VM

/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

 

# Text console, bridged, HD qcow2

# HTTP + Kickstart

virt-install \

--virt-type kvm \

--name=$1 \

--disk path=/var/lib/libvirt/images/$1.qcow2,size=16,format=qcow2 \

--ram=1024 \

--vcpus=1 \

--os-variant=rhel7 \

--network bridge=virbr0 \

--graphics none \

--console pty,target_type=serial \

--location $mirror \

-x "ks=https://$bridge/conf/vm2.ks console=ttyS0,115200n8 serial"

 

Pour échapper à la console texte :

CTRL+] (Linux)

CTRL+ALT+* (Mac OS X)

7. Accéder à la console

7.1. Accéder à la console graphique

Via une session Xwindows :

ou

ou

netstat -tln|grep :59

 

vncviewer x.x.x.x:5900

7.2. Activer ttyS0 dans grub

Il faut nécessairement que la machine virtuelle dispose d’une console ttyS0 émulée !

Si la machine n’a pas été configurée avec ce paramètre grub, il faut editer le fichier /etc/default/grub en ajoutant console=ttyS0 ) à la variable GRUB_CMDLINE_LINUX. Le fichier /etc/default/grub devrait ressembler à ceci

# cat /etc/default/grub

GRUB_TIMEOUT=5

GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"

GRUB_DEFAULT=saved

GRUB_DISABLE_SUBMENU=true

GRUB_TERMINAL="serial console"

GRUB_SERIAL_COMMAND="serial --speed=115200"

GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=vg0/root rd.lvm.lv=vg0/swap console=ttyS0,115200n8"

GRUB_DISABLE_RECOVERY="true"

 

Exécuter :

grub2-mkconfig -o /boot/grub2/grub.cfg

reboot

7.3. Accès à la console texte

# virsh console vm1

Connected to domain vm1

Escape character is ^]

 

CentOS Linux 7 (Core)

Kernel 3.10.0-229.el7.x86_64 on an x86_64

 

localhost login:

8. Installation d’un invité MS-Windows

osinfo-query os | grep Microsoft

A condition de disposer d’un ISO de Windows 7, voici un script de configuration d’une VM Windows en mode HVM :

#!/bin/bash

# File vm-install5.sh

 

#Stop and undefine the VM

/bin/virsh destroy $1; /bin/virsh undefine $1 --remove-all-storage

 

# Graphical console, bridged, cd-rom

virt-install \

--virt-type kvm \

--name=$1 \

--disk path=/var/lib/libvirt/images/$1.qcow2,size=16,format=qcow2 \

--cdrom /var/win7.iso \

--ram=2048 \

--vcpus=2 \

--arch=x86_64

--os-type=windows \

--os-variant=win7 \

--hvm \

--network bridge=virbr0 \

--keymap=fr \

--sound \

--vnc

On a aussi besoin des pilotes virtio si on utilise la paravirtualisation :

#!/bin/bash

# File vm-install6.sh

...

Voir Wiki sur les pilotes virtio :

wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo -O /etc/yum.repos.d/virtio-win.repo

 

yum install virtio-win

/usr/share/virtio-win/*.iso contient tous les pilotes virtio.

Après l’installation insérer l’iso virtio-tools, mais avant trouver le lecteur cd :

virsh change-media vm3 hdb /usr/share/virtio-win/virtio-win.iso

9. Manipulation de disques

9.1 Conversion de disques

raw vers qcow2

Pour convertir un disque raw vers qcow2 :

#!/bin/bash

 

# File raw2qcow2.sh

path=/var/lib/libvirt/images/$1

 

virsh list

virsh suspend $1

ls -lh $path.img

echo "Conversion du disque"

qemu-img convert -c -O qcow2 $path.img $path.qcow2

mv $path.img $path.old

mv $path.qcow2 $path.img

virsh resume $1

ls -lh $path.*

vdi vers raw

Pour convertir un disque VB vdi vers raw :

$ VBoxManage clonehd --format RAW WindowsXP.vdi WindowsXP.raw

0%...10%...20%...30%...50%...70%...80%...90%...100%

Clone hard disk created in format 'RAW'. UUID: cfe44508-d957-4c8c-b5c5-2b4f266830d8

9.2. Redimensionnement de disques

9.3 Import d’une VM via son disque

Import d’une VM via son disque (converti d’une autre solution par exemple) avec virt-install --import --noautoconsole.

#!/bin/bash

## This script import and launch minimal KVM images with a text console ##

## First download all the qcow2 images on https://get.goffinet.org/kvm/ ##

## Usage : bash define-guest.sh <name> <image> ##

## Reset root password with the procedure : ##

## https://linux.goffinet.org/processus_et_demarrage.html#10-password-recovery  ##

## Please check all the variables ##

# First parmater as name

name=$1

# Secund parameter image name avaible on "https://get.goffinet.org/kvm/"

# Image name : 'debian7', 'debian8', 'centos7', 'ubuntu1604', 'metasploitable', kali

image="$2.qcow2"

# Generate an unique string

uuid=$(uuidgen -t)

# VCPUs

vcpu="1"

# The new guest disk name

disk="${name}-${uuid:25}.qcow2"

# Diskbus can be 'ide', 'scsi', 'usb', 'virtio' or 'xen'

diskbus="virtio"

size="8"

# Hypervisor can be 'qemu', 'kvm' or 'xen'

hypervisor="kvm"

# RAM in Mb

memory="256"

# Graphics 'none' or 'vnc'

graphics="none"

# Network inetrface and model 'virtio' or 'rtl8139' or 'e1000'

interface="virbr0"

model="virtio"

# Parameters for metasploitable guests

if [ $image = "metasploitable.qcow2" ]; then

diskbus="scsi"

memory="512"

model="e1000"

fi

# Parameters for Kali guests

if [ $image = "kali.qcow2" ]; then

memory="1024"

size="16"

fi

## Local image copy to the default storage pool ##

cp ./$image /var/lib/libvirt/images/$disk

## Import and lauch the new guest ##

virt-install \

--virt-type $hypervisor \

--name=$name \

--disk path=/var/lib/libvirt/images/$disk,size=$size,format=qcow2,bus=$diskbus \

--ram=$memory \

--vcpus=$vcpu \

--os-variant=linux \

--network bridge=$interface,model=$model \

--graphics $graphics \

--console pty,target_type=serial \

--import \

--noautoconsole

9.4. Migration V2V

9.5. Manipulation de disques

Comment ajouter un disque vide à la volée sur un domaine invité ?

Ce script demande trois paramètres :

https://raw.githubusercontent.com/goffinet/virt-scripts/master/add-storage.sh

#!/bin/bash

# Variables

guest=$1

disk=/var/lib/libvirt/images/${1}-${2}.img

size=$3

seek=$[${size}*1024]

# Create Spare Disk with dd

dd if=/dev/zero of=$disk  bs=1M seek=$seek count=0

# Or create a qcow2 disk

#qemu-img create -f qcow2 -o preallocation=metadata $disk ${size}G

# Attach the disk on live guest with persistence

virsh attach-disk $guest $disk $2 --cache none --live --persistent

# Detach the disk

#virsh detach-disk $guest $disk --persistent --live

Note.

10. Storage Pools / Storage Volumes

Ajouter un pool pour stocker les disques des domaines

virsh pool-define-as Images dir - - - - /home/so/Documents/kvm/images

virsh pool-list --all

virsh pool-build Images

virsh pool-start Images

virsh pool-autostart Images

virsh pool-list

virsh pool-info Images

Storage Pools

11. Live Migration

12. Réseau

Lister les réseaux virtuels disponibles :

Lister les adresses IP attribuées par un réseau virtuel :

virsh net-dhcp-leases default

 Expiry Time          MAC address        Protocol  IP address                Hostname        Client ID or DUID

-------------------------------------------------------------------------------------------------------------------

 2017-02-16 16:52:03  52:54:00:15:35:f8  ipv4      192.168.122.129/24        arch            ff:00:15:35:f8:00:01:00:01:20:33:48:d8:52:54:00:01:fb:0d

 2017-02-16 16:52:15  52:54:00:3d:6c:39  ipv4      192.168.122.126/24        u1              -

 2017-02-16 16:52:11  52:54:00:50:ac:4a  ipv4      192.168.122.253/24        c1              -

 2017-02-16 16:52:05  52:54:00:87:40:65  ipv4      192.168.122.130/24        d1              -

 2017-02-16 16:52:09  52:54:00:91:31:a2  ipv4      192.168.122.212/24        k1              -

 2017-02-16 16:52:20  52:54:00:b1:a7:a7  ipv4      192.168.122.173/24        m1              -

 

Obtenir la base d’une définition de réseau virtuel (ici default) dans un fichier lab.xml :

virsh net-dumpxml default > lab.xml

La commande uuidgen permet de générer un uuid :

Si on défini un nouveau réseau “lab” utilisant l’interface virbr1 pour laquelle le NAT est activé, voici à quoi se fichier devrait ressembler :

<network>

  <name>lab</name>

  <uuid>8293bf7a-ccf6-461b-8466-a058e7346d79</uuid>

  <forward mode='nat'>

    <nat>

      <port start='1024' end='65535'/>

    </nat>

  </forward>

  <bridge name='virbr1' stp='on' delay='0'/>

  <mac address='52:54:00:63:e8:10'/>

  <ip address='192.168.22.254' netmask='255.255.255.0'>

    <dhcp>

      <range start='192.168.22.100' end='192.168.22.150'/>

    </dhcp>

  </ip>

</network>

La balise forward mode peut prendre des valeurs comme nat, route, bridge, etc. En son absence le réseau est isolé.

Installation du nouveau réseau lab :

Démarrage du réseau :

Ensuite, faire en sorte qu’il démarre automatiquement :

Pour attacher un domaine existant au réseau lab, il faut créer un fichier qui reprend les paramètres d’une interface :

<interface type='bridge'>

      <mac address='52:54:00:f7:e3:53'/>

      <source bridge='virbr1'/>

      <target dev='vnet0'/>

      <model type='virtio'/>

      <alias name='net0'/>

      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>

</interface>

Pour mettre à jour l’attachement de la carte réseau :

virsh update-device vm-test virbr1.xml

Ajout d’une seconde interface

On peut prendre une définition d’interface comme suit. Il s’agit de modifier balise “alias name” en mettant une nouvelle valeur net1 par exemple et en modifiant l’adresse MAC pour la rendre originale :

<interface type='bridge'>

      <mac address='52:54:00:aa:bb:cc'/>

      <source bridge='virbr1'/>

      <target dev='vnet0'/>

      <model type='virtio'/>

      <alias name='net0'/>

</interface>

On peut alors attacher la carte au domaine en “live” :

virsh attach-device nom_de_domaine fichier.xml

Réseau isolé

Création d’un réseau isolé nommé “lan” sur l’interface “vrirbr3”

https://github.com/goffinet/virt-scripts/blob/master/add-isolated-bridge.sh

#!/bin/bash

# Create an isolated bridge

 

bridge="virbr3"

name=lan

path=/tmp

cat << EOF > $path/$name.xml

<network>

  <name>$name</name>

  <bridge name='$bridge' stp='on' delay='0'/>

</network>

EOF

 

virsh net-destroy $name

virsh net-create $path/$name.xml

#virsh net-autostart $name

Exercice : créer un routeur virtuel Linux

Voir chapitre sur le routage et le pare-feu :

  1. 1.Solution Routeur virtuel (libvirtd) interne sans DHCP 

  2. 2.Solution KVM avec un routeur Centos/Debian Firewalld 

  3. 3.Solution KVM avec OpenWRT 

13. Exemples de scripts automatiques

13.1. virt-builder

Le logiciel virt-builder permet de construire rapidement une VM à partir d’une image disponible sur le site de libguestfs. Il est paramétrable : voir https://libguestfs.org/virt-builder.1.html.

On citera aussi le projet OZ : https://github.com/clalancette/oz.

13.2. Exemples de code de déploiement

14. Automation des installations

14.1. Améliorations des scripts précédents

On peut tenter d’améliorer les scripts des exercices précédents et se poser quelques questions

Configuration profils de VM

Configuration Kickstart

14.2. Projet

Déploiement silencieux selon un profil de VM et d’installation.

Etude de cas :

Résumé

Pré-requis

Cet exercice est réalisé sous Centos 7.

Un serveur Web sur l’hyperviseur, httpd par exemple, ou situé ailleurs rend disponible deux dossiers dans /var/www/html :

Deux sources sont à définir :

Profil de machine virtuelle “small”

Un script de création VM “small”

profil d’installation “core”

Configuration du système prédéfini dans un fichier Kickstart auquel correspond un profil d’installation Centos 7 avec un minimum de paquets, authentification à clé SSH et partionnement LVM2.

Il est nécessaire copier la clé publique de l’administrateur afin d’assurer

14.3. Première procédure

Firewalld désactivé

Pour les besoins de l’exercice, on désactivera le pare-feu.

Création d’un réseau NAT dénommé lab

Script virt-install “autovm.sh”

#!/bin/bash

 

## usage : autovm.sh [type] [nom domaine]

##         autovm.sh $1 $2

## types (appel d'un fichier kickstarts):

##         core

 

## Variables

## 1. $type : Fichier Kickstart

type=$1

## 2. $name : Nom du domaine

name=$2

## 3. $vol : Emplacement des disques

vol=/var/lib/libvirt/images

## 4. $conf : Emplacement HTTP des fichiers Kickstart

conf=https://192.168.122.1/conf

## 5. $mirror : Sources d'installation HTTP

mirror=https://192.168.122.1/repo

## Miroirs publics

#mirror=https://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64

#mirror=https://ftp.belnet.be/ftp.centos.org/7/os/x86_64

#mirror=https://mirror.i3d.net/pub/centos/7/os/x86_64

## 6. $temp : nom temporaire pour le fichier Kickstart

temp="$name-$(uuidgen | cut -d - -f 1)"

## 7. $www : emplacement physique des fichiers de configuration

www=/var/www/html/conf

 

gest_dom ()

{

## Gestion des noms utilisés, ici pour un lab (à améliorer)

## Arrêt et retrait de la VM

echo "Arrêt et retrait de la VM $name"

/bin/virsh destroy $name; /bin/virsh undefine $name --remove-all-storage

}

 

 

prep_ks ()

{

## Préparation du fichier Kickstart

echo "Préparation du fichier Kickstart"

cp $www/$type.ks $www/$temp.ks

chown apache:apache $www/$temp.ks

## Report du hostname

sed -i "s/network --hostname=.*/network --hostname=$name/g" $www/$temp.ks

##

}

 

virt_install ()

{

## Démarrage de l'installation du domaine

echo "Démarrage de l'installation du domaine $name"

## Installation et lancement silencieux en mode texte

## selon la baseline définie Centos 7 1GB/1vCPU/HD8GB/1NIC/ttyS0

nohup \

virt-install \

--virt-type kvm \

--name=$name \

--disk path=/var/lib/libvirt/images/$name.qcow2,size=8,format=qcow2 \

--ram=1024 \

--vcpus=1 \

--os-variant=rhel7 \

--network bridge=virbr0 \

--graphics none \

--noreboot \

--console pty,target_type=serial \

--location $mirror \

-x "ks=$conf/$temp.ks console=ttyS0,115200n8 serial" \

> /dev/null 2>&1 &

 

 

## choix installation cdrom avec Kickstart local

#ks=/var/www/html/conf

#iso=path/to/iso

#--cdrom $iso \

#--initrd-inject=/$temp.ks -x "ks=file:/$temp.ks console=ttyS0,115200n8 serial" \

}

 

gest_dom

prep_ks

virt_install

 

# rm -f $www/$temp.ks

Fichier kickstart core.ks

## hostname

## bootproto dhcp ou static

##NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT

## vda             252:0    0    8G  0 disk

## ├─vda1          252:1    0  500M  0 part /boot

## ├─vda2          252:2    0  6,7G  0 part        (auto-grow)

## │ └─local0-root 253:0    0  3,9G  0 lvm  /

## └─vda3          252:3    0  820M  0 part [SWAP] (auto-grow)

## install @core (minimum de paquets)

## post-install : update

## post-configuration ssh

install

keyboard --vckeymap=be-oss --xlayouts='be (oss)'

reboot

rootpw --plaintext testtest

timezone Europe/Brussels

url --url="https://192.168.122.1/repo"

lang fr_BE

firewall --disabled

network --bootproto=dhcp --device=eth0

network --hostname=template

# network --device=eth0 --bootproto=static --ip=192.168.22.10 --netmask 255.255.255.0 --gateway 192.168.22.254 --nameserver=192.168.22.11 --ipv6 auto

auth  --useshadow  --passalgo=sha512

text

firstboot --enable

skipx

ignoredisk --only-use=vda

bootloader --location=mbr --boot-drive=vda

zerombr

clearpart --all --initlabel

part /boot --fstype="xfs" --ondisk=vda --size=500

part swap --recommended

part pv.00 --fstype="lvmpv" --ondisk=vda --size=500 --grow

volgroup local0 --pesize=4096 pv.00

logvol /  --fstype="xfs"  --size=4000 --name=root --vgname=local0

%packages

@core

%end

%post

#yum -y update

mkdir /root/.ssh

curl https://192.168.122.1/conf/id_rsa.pub > /root/.ssh/authorized_keys

sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config

%end

Le projet a evolué en des scripts plus succints, notamment avec le script https://raw.githubusercontent.com/goffinet/virt-scripts/master/auto-install.sh :

#!/bin/bash

 

image=$1 # centos, debian, ubuntu

name=$2

fr_ubuntu_mirror=https://fr.archive.ubuntu.com/ubuntu/dists/xenial/main/installer-amd64/

fr_debian_mirror=https://ftp.debian.org/debian/dists/jessie/main/installer-amd64/

ovh_ubuntu_mirror=https://mirror.ovh.net/ubuntu/dists/xenial/main/installer-amd64/

ovh_debian_mirror=https://debian.mirrors.ovh.net/debian/dists/jessie/main/installer-amd64/

ovh_centos_mirror=https://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64

belnet_ubuntu_mirror=https://ftp.belnet.be/ubuntu.com/ubuntu/dists/xenial/main/installer-amd64/

belnet_debian_mirror=https://ftp.belnet.be/debian/dists/jessie/main/installer-amd64/

belnet_centos_mirror=https://ftp.belnet.be/ftp.centos.org/7/os/x86_64

local_ubuntu_iso=/var/lib/iso/ubuntu-16.04.1-server-amd64.iso

url_ubuntu_iso=https://releases.ubuntu.com/16.04/ubuntu-16.04.1-server-amd64.iso

local_debian_iso=/var/lib/iso/debian-8.6.0-amd64-netinst.iso

url_debian_iso=https://cdimage.debian.org/debian-cd/8.6.0/amd64/iso-cd/debian-8.6.0-amd64-netinst.iso

local_centos_iso=/var/lib/iso/CentOS-7-x86_64-DVD-1611.iso

url_centos_iso=https://ftp.belnet.be/ftp.centos.org/7/isos/x86_64/CentOS-7-x86_64-DVD-1611.iso

ubuntu_mirror=$belnet_ubuntu_mirror

debian_mirror=$fr_debian_mirror

centos_mirror=$belnet_centos_mirror

check_apache () {

yum install -y httpd curl || apt-get install apache2 curl

firewall-cmd --permanent --add-service=http

firewall-cmd --reload

systemctl enable httpd

systemctl start httpd

mkdir -p /var/www/html/conf

echo "this is ok" > /var/www/html/conf/ok

local check_value="this is ok"

local check_remote=$(curl -s https://127.0.0.1/conf/ok)

if [ "$check_remote"="$check_value" ] ; then

 echo "Apache is working"

else

 echo "Apache is not working"

 exit

fi

}

 

ubuntu_install () {

local url=https://192.168.122.1/conf/ubuntu1604-preseed.cfg

local mirror=$ubuntu_mirror

 

touch /var/www/html/conf/ubuntu1604-preseed.cfg

cat << EOF > /var/www/html/conf/ubuntu1604-preseed.cfg

d-i debian-installer/language                               string      en_US:en

d-i debian-installer/country                                string      US

d-i debian-installer/locale                                 string      en_US

d-i debian-installer/splash                                 boolean     false

d-i localechooser/supported-locales                         multiselect en_US.UTF-8

d-i pkgsel/install-language-support                         boolean     true

d-i console-setup/ask_detect                                boolean     false

d-i keyboard-configuration/modelcode                        string      pc105

d-i keyboard-configuration/layoutcode                       string      be

d-i debconf/language                                        string      en_US:en

d-i netcfg/choose_interface                                 select      auto

d-i netcfg/dhcp_timeout                                     string      5

d-i mirror/country                                          string      manual

d-i mirror/http/hostname                                    string      fr.archive.ubuntu.com

d-i mirror/http/directory                                   string      /ubuntu

d-i mirror/http/proxy                                       string

d-i time/zone                                               string      Europe/Paris

d-i clock-setup/utc                                         boolean     true

d-i clock-setup/ntp                                         boolean     false

d-i passwd/root-login                                       boolean     false

d-i passwd/make-user                                        boolean     true

d-i passwd/user-fullname                                    string      user

d-i passwd/username                                         string      user

d-i passwd/user-password                                    password    testtest

d-i passwd/user-password-again                              password    testtest

d-i user-setup/allow-password-weak                          boolean     true

d-i passwd/user-default-groups                              string      adm cdrom dialout lpadmin plugdev sambashare

d-i user-setup/encrypt-home                                 boolean     false

d-i apt-setup/restricted                                    boolean     true

d-i apt-setup/universe                                      boolean     true

d-i apt-setup/backports                                     boolean     true

d-i apt-setup/services-select                               multiselect security

d-i apt-setup/security_host                                 string      security.ubuntu.com

d-i apt-setup/security_path                                 string      /ubuntu

tasksel tasksel/first                                       multiselect openssh-server

d-i pkgsel/include                                          string      openssh-server python-simplejson vim

d-i pkgsel/upgrade                                          select      safe-upgrade

d-i pkgsel/update-policy                                    select      none

d-i pkgsel/updatedb                                         boolean     true

d-i partman/confirm_write_new_label                         boolean     true

d-i partman/choose_partition                                select      finish

d-i partman/confirm_nooverwrite                             boolean     true

d-i partman/confirm                                         boolean     true

d-i partman-auto/purge_lvm_from_device                      boolean     true

d-i partman-lvm/device_remove_lvm                           boolean     true

d-i partman-lvm/confirm                                     boolean     true

d-i partman-lvm/confirm_nooverwrite                         boolean     true

d-i partman-auto-lvm/no_boot                                boolean     true

d-i partman-md/device_remove_md                             boolean     true

d-i partman-md/confirm                                      boolean     true

d-i partman-md/confirm_nooverwrite                          boolean     true

d-i partman-auto/method                                     string      lvm

d-i partman-auto-lvm/guided_size                            string      max

d-i partman-partitioning/confirm_write_new_label            boolean     true

d-i grub-installer/only_debian                              boolean     true

d-i grub-installer/with_other_os                            boolean     true

d-i finish-install/reboot_in_progress                       note

d-i finish-install/keep-consoles                            boolean     false

d-i cdrom-detect/eject                                      boolean     true

d-i preseed/late_command in-target sed -i 's/PermitRootLogin\ prohibit-password/PermitRootLogin\ yes/' /etc/ssh/sshd_config ; in-target wget https://gist.githubusercontent.com/goffinet/f515fb4c87f510d74165780cec78d62c/raw/7cf2c788c1c5600f7433d16f8f352c877a281a6a/ubuntu-grub-console.sh ; in-target sh ubuntu-grub-console.sh

EOF

 

virt-install \

--virt-type kvm \

--name=$name \

--disk path=/var/lib/libvirt/images/$name.qcow2,size=8,format=qcow2 \

--ram=512 \

--vcpus=1 \

--os-variant=ubuntusaucy \

--network bridge=virbr0 \

--graphics none \

--console pty,target_type=serial \

--location $mirror \

-x "auto=true hostname=$name domain= url=$url text console=ttyS0,115200n8 serial"

}

 

debian_install () {

local url=https://192.168.122.1/conf/debian8-preseed.cfg

local mirror=$debian_mirror

 

touch /var/www/html/conf/debian8-preseed.cfg

cat << EOF > /var/www/html/conf/debian8-preseed.cfg

d-i debian-installer/locale string en_US

d-i keyboard-configuration/xkb-keymap select be

d-i netcfg/choose_interface select auto

d-i netcfg/get_hostname string unassigned-hostname

d-i netcfg/get_domain string unassigned-domain

d-i netcfg/wireless_wep string

d-i mirror/country string manual

d-i mirror/http/hostname string ftp.debian.org

d-i mirror/http/directory string /debian

d-i mirror/http/proxy string

d-i passwd/make-user boolean false

d-i passwd/root-password password testtest

d-i passwd/root-password-again password testtest

d-i clock-setup/utc boolean true

d-i time/zone string Europe/Paris

d-i clock-setup/ntp boolean true

d-i partman-auto/method string lvm

d-i partman-lvm/device_remove_lvm boolean true

d-i partman-md/device_remove_md boolean true

d-i partman-lvm/confirm boolean true

d-i partman-lvm/confirm_nooverwrite boolean true

d-i partman-auto/choose_recipe select atomic

d-i partman-partitioning/confirm_write_new_label boolean true

d-i partman/choose_partition select finish

d-i partman/confirm boolean true

d-i partman/confirm_nooverwrite boolean true

d-i partman-md/confirm boolean true

d-i partman-partitioning/confirm_write_new_label boolean true

d-i partman/choose_partition select finish

d-i partman/confirm boolean true

d-i partman/confirm_nooverwrite boolean true

tasksel tasksel/first multiselect standard

d-i pkgsel/include string openssh-server vim

d-i pkgsel/upgrade select full-upgrade

popularity-contest popularity-contest/participate boolean false

d-i grub-installer/only_debian boolean true

d-i grub-installer/with_other_os boolean true

d-i grub-installer/bootdev  string /dev/vda

d-i finish-install/keep-consoles boolean true

d-i finish-install/reboot_in_progress note

d-i preseed/late_command string in-target sed -i 's/PermitRootLogin\ without-password/PermitRootLogin\ yes/' /etc/ssh/sshd_config; in-target wget https://gist.githubusercontent.com/goffinet/f515fb4c87f510d74165780cec78d62c/raw/7cf2c788c1c5600f7433d16f8f352c877a281a6a/ubuntu-grub-console.sh ; in-target sh ubuntu-grub-console.sh

EOF

 

virt-install \

--virt-type kvm \

--name=$name \

--disk path=/var/lib/libvirt/images/$name.qcow2,size=8,format=qcow2 \

--ram=512 \

--vcpus=1 \

--os-variant=debianwheezy \

--network bridge=virbr0 \

--graphics none \

--console pty,target_type=serial \

--location $mirror \

-x "auto=true hostname=$name domain= url=$url text console=ttyS0,115200n8 serial"

}

 

centos_install () {

 

local url=https://192.168.122.1/conf/centos7.ks

local mirror=$centos_mirror

 

read -r -d '' packages <<- EOM

@core

wget

EOM

 

touch /var/www/html/conf/centos7.ks

cat << EOF > /var/www/html/conf/centos7.ks

install

reboot

rootpw --plaintext testtest

keyboard --vckeymap=be-oss --xlayouts='be (oss)'

timezone Europe/Paris --isUtc

#timezone Europe/Brussels

lang en_US.UTF-8

#lang fr_BE

#cdrom

url --url="$mirror"

firewall --disabled

network --bootproto=dhcp --device=eth0

network --bootproto=dhcp --device=eth1

network --hostname=$name

# network --device=eth0 --bootproto=static --ip=192.168.22.10 --netmask 255.255.255.0 --gateway $bridgeip4 --nameserver=$bridgeip4 --ipv6 auto

#auth  --useshadow  --passalgo=sha512

text

firstboot --enable

skipx

ignoredisk --only-use=vda

bootloader --location=mbr --boot-drive=vda

zerombr

clearpart --all --initlabel

#autopart --type=thinp # See the bug resolved in 7.3 https://bugzilla.redhat.com/show_bug.cgi?id=1290755

autopart --type=lvm

#part /boot --fstype="xfs" --ondisk=vda --size=500

#part swap --recommended

#part pv.00 --fstype="lvmpv" --ondisk=vda --size=500 --grow

#volgroup local0 --pesize=4096 pv.00

#logvol /  --fstype="xfs"  --size=4000 --name=root --vgname=local0

%packages

$packages

%end

%post

yum -y update && yum -y upgrade

#mkdir /root/.ssh

#curl ${conf}/id_rsa.pub > /root/.ssh/authorized_keys

#sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config

%end

EOF

 

 

virt-install \

--virt-type=kvm \

--name=$name \

--disk path=/var/lib/libvirt/images/$name.qcow2,size=8,format=qcow2 \

--ram=2048 \

--vcpus=1 \

--os-variant=rhel7 \

--network bridge=virbr0 \

--graphics none \

--noreboot \

--console pty,target_type=serial \

--location $mirror \

-x "auto=true hostname=$name domain= ks=$url text console=ttyS0,115200n8 serial"

}

 

start_install () {

if [ $image = centos ] ; then

 centos_install

elif [ $image = debian ] ; then

 debian_install

elif [ $image = ubuntu ] ; then

 ubuntu_install

else

 echo "Erreur dans le script : ./auto-install.sh [ centos | debian | ubuntu ] nom_de_vm"

 exit

fi

}

 

check_apache

start_install

14.4. Automation Ansible

Pré-requis

Seul pré-requis : Sytème Linux (Centos 7) avec un accès ssh avec authentification avec clé et Python installé.

Une résolution de nom robuste est conseillée.

Concepts

Installation

yum install ansible

echo "nameserver 192.168.122.1" >> /etc/resolv.conf

mv /etc/ansible/hosts /etc/ansible/hosts.old

echo -e "[lab]\nvm0[1:4]" > /etc/ansible/hosts

cat /etc/ansible/hosts

Modules

ansible all -m ping

ansible vm01 -m ping

ansible all -m setup

ansible lab -m yum -a "name=openssh-server state=present"

Playbooks

14.5. Seconde procédure

Dans cette seconde procédure, on pourra choisir le profil de la machine virtuelle à partir d’un seul script.

Ce script vise à créer une machine virtuelle KVM d’une certaine capacité (small, medium, large) de manière automatique.

L’installation est minimale mais suffisante (core) pour assurer la gestion par Ansible et déployer des containers en tant que services.

On peut l’améliorer dans le profilage des installations (pré-installation, services, fichiers de configuration mais aussi dans la maintenance de la machine virtuelle (fin de l’installation, suppression du fichier Kickstart, –> via boucle while/surveillance du processus lancé, génération de rapports, logs) ou encore la gestion des erreurs.

Une option “gold image” ou modèle qui permettrait de préparer une VM et de cloner une telle installation fraîche serait un must, car elle répondrait à autre approche d’une solution de déploiement automatique de machines virtuelles.

Pour comprendre ce script, on le lira en trois temps :

  1. 1.variables générales au début 

#/bin/bash

# fichier autovm.sh

## usage : autovm.sh [type] [nom domaine]

##         autovm.sh $1 $2

## Création et installation automatisée Fedora/Centos 7

## types (profils, baselines):

##         small, medium ou large

##

## Variables générales

## 1. $name : Nom du domaine

name=$2

## 2. $type : type d'installation

type=$1

## 3. $vol : Emplacement des disques

vol=/var/lib/libvirt/images

## 4. $conf : Emplacement HTTP des fichiers Kickstart

## Serveur Web sur l'hyperviseur (adresse du réseau "Default")

conf=https://192.168.122.1/conf

## 5. $mirror : Sources d'installation HTTP

mirror=https://192.168.122.1/repo

## Miroirs publics

#mirror=https://centos.mirrors.ovh.net/ftp.centos.org/7/os/x86_64

#mirror=https://ftp.belnet.be/ftp.centos.org/7/os/x86_64

#mirror=https://mirror.i3d.net/pub/centos/7/os/x86_64

## 6. $temp : nom temporaire pour le fichier Kickstart

temp="$name-$(uuidgen | cut -d - -f 1)"

## 7. $www : emplacement physique des fichiers de configuration

www=/var/www/html/conf

 

gest_dom ()

{

## Gestion des noms utilisés, ici pour un lab (à améliorer)

## Arrêt et retrait de la VM

echo "Arrêt et retrait de la VM $name"

/bin/virsh destroy $name; /bin/virsh undefine $name

#Erase the VM disk

rm -f $vol/$name.*

}

 

 

prep_ks ()

{

## Préparation du fichier Kickstart

echo "Préparation du fichier Kickstart"

 

##

touch $www/$temp.ks

cat << EOF > $www/$temp.ks

install

keyboard --vckeymap=be-oss --xlayouts='be (oss)'

reboot

rootpw --plaintext testtest

timezone Europe/Brussels

url --url="$mirror"

lang fr_BE

firewall --disabled

network --bootproto=dhcp --device=eth0

network --hostname=$name

# network --device=eth0 --bootproto=static --ip=192.168.22.10 --netmask 255.255.255.0 --gateway 192.168.22.254 --nameserver=192.168.22.11 --ipv6 auto

auth  --useshadow  --passalgo=sha512

text

firstboot --enable

skipx

ignoredisk --only-use=vda

bootloader --location=mbr --boot-drive=vda

zerombr

clearpart --all --initlabel

part /boot --fstype="xfs" --ondisk=vda --size=500

part swap --recommended

part pv.00 --fstype="lvmpv" --ondisk=vda --size=500 --grow

volgroup local0 --pesize=4096 pv.00

logvol /  --fstype="xfs"  --size=4000 --name=root --vgname=local0

%packages

@core

%end

%post

#yum -y update

mkdir /root/.ssh

curl $conf/id_rsa.pub > /root/.ssh/authorized_keys

sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config

%end

EOF

 

chown apache:apache $www/$temp.ks

}

 

virt_install ()

{

 

installation ()

{

## Démarrage de l'installation du domaine

echo "Démarrage de l'installation du domaine $name"

## Installation et lancement silencieux en mode texte

## selon le profil (baseline) défini dans la variable $type

nohup \

/bin/virt-install \

--virt-type kvm \

--name=$name \

--disk path=$vol/$name.$format,size=$size,format=$format \

--ram=$ram \

--vcpus=$vcpus \

--os-variant=rhel7 \

--network bridge=$bridge \

--graphics none \

--noreboot \

--console pty,target_type=serial \

--location $mirror \

-x "ks=$conf/$temp.ks console=ttyS0,115200n8 serial" \

> /dev/null 2>&1 &

 

## choix installation cdrom avec Kickstart local

#ks=/var/www/html/conf

#iso=path/to/iso

#--cdrom $iso \

#--initrd-inject=/$temp.ks -x "ks=file:/$temp.ks console=ttyS0,115200n8 serial" \

}

 

if [ $type = small ] ; then

        size=8

        format=qcow2

        ram=1024

        vcpus=1

        bridge=virbr0

    installation

elif [ $type = medium ] ; then

        size=16

        format=qcow2

        ram=2048

        vcpus=2

        bridge=virbr0

    installation

elif [ $type = large ] ; then

        size=32

        format=qcow2

        ram=4096

        vcpus=4

        bridge=virbr0

    installation

else

        exit

fi

}

 

gest_dom

prep_ks

virt_install

 

# rm -f $www/$temp.ks

15. Surveillance

16. Commandes Virsh

virsh # version

Compiled against library: libvirt 2.0.0

Using library: libvirt 2.0.0

Utilisation de l'API : QEMU 2.0.0

Exécution de l'hyperviseur : QEMU 1.5.3

16.1. Domain Management (help keyword ‘domain’)

16.2. Domain Monitoring (help keyword ‘monitor’)

16.3. Host and Hypervisor (help keyword ‘host’)

16.4. Interface (help keyword ‘interface’)

16.5. Network Filter (help keyword ‘filter’)

16.6. Networking (help keyword ‘network’)

16.7. Node Device (help keyword ‘nodedev’)

16.8. Secret (help keyword ‘secret’)

16.9. Snapshot (help keyword ‘snapshot’)

16.10. Storage Pool (help keyword ‘pool’)

16.11. Storage Volume (help keyword ‘volume’)

16.12. Virsh itself (help keyword ‘virsh’)